#include "ObjectManage.h"
//#include <cstring>

//#include "..\AlgebraicBsplineSurface.h"

//#include "..\base\base3d.h" // For base method


// Initiatiate the object managers
CABSObjManage CObjManageFactory::_absObjManage;

//////////////////////////////////////////////////////////////////////////
// Implementation of abs object manager
CABSObjManage::CABSObjManage()
{
	_modelID = -1;
	 _nVol = _nMesh = _nFeng = _nABS = _nMorf = 0;
	//_MorfABS	= NULL;
	//_VolModeling = NULL;
	//_MeshModeling = NULL;
	//_FengModeling = NULL;
	//_ABS = NULL;
}

//CABSObjManage::~CABSObjManage()
//{
//	ClearObjects(); 
//}
	
void CABSObjManage::ClearAppObjects()
{
	// Clear data in abs object manager
	ClearMorfABS();
	ClearVolumeModeling();
	ClearMeshModeling();
	ClearFengModeling();
	ClearABS();
}
void CABSObjManage::ClearMorfABS()
{
	for (int i=0; i<_nMorf; i++)
	{
		if(_MorfABS[i])	delete (_MorfABS[i]); _MorfABS[i] = NULL;
	}
}

void CABSObjManage::ClearVolumeModeling()
{
	for (int i=0; i<_nVol; i++)
	{
		if(_VolModeling[i])	delete (_VolModeling[i]); _VolModeling[i] = NULL;
	}
}

void CABSObjManage::ClearMeshModeling()
{
	for(int i=0; i<_nMesh; i++)
	{
		if(_MeshModeling[i])	delete _MeshModeling[i]; _MeshModeling[i] = NULL;
	}
}

void CABSObjManage::ClearFengModeling()
{
	for(int i=0; i<_nFeng; i++)
	{
		if(_FengModeling[i])	delete _FengModeling[i]; _FengModeling[i] = NULL;
	}
}

void CABSObjManage::ClearABS()
{
	for(int i=0; i<_nABS; i++)
	{
		if(_ABS[i])	delete _ABS[i]; _ABS[i] = NULL;
	}
}

ABSSf* CABSObjManage::GetABS()
{ 
	switch (_modelID)
	{
		case 0:
			return _ABS[_nABS-1]; 
			break;
		case 1:
			return GetFengModeling()->m_pABS;
			break;
		case 2:
			return GetMeshModeling()->m_pABS;
			break;
		case 3:
			return GetVolumeModeling()->m_pABS;
			break;
		case 4:
			return GetMorfABS()->m_pABS;
		default:
			return NULL;
			break;
	}
}


//////////////////////////////////////////////////////////////////////////
// Implementation of CObjManageFactory

void CObjManageFactory::ClearAllObject()
{
	// Clear all objects in each obj manager
	_absObjManage.ClearObjects();

	return;
}

bool CObjManageFactory::LoadObject(LPCTSTR lpszPathName, bool bMorf)
{	
	const WCHAR* ext = wcsrchr( lpszPathName, L'.');
	if(!ext) 
		return false;

	//ClearAllObject();
	ABSSf* ori;
	if(bMorf)
	{
		ori = GetABSObjManage().GetABS();
	}

	if(_wcsicmp(ext, L".fmd") == 0)
	{
		FengModeling* pFeng = new FengModeling(lpszPathName);
		_absObjManage.SetFengModeling(pFeng);
		goto out;
	}
	
	if(_wcsicmp(ext, L".abs") == 0)
	{
		ABSSf* abs = new ABSSf;

		char filename[MAX_PATH];
		WideCharToMultiByte(CP_ACP, 0, lpszPathName, -1, filename, MAX_PATH, NULL, NULL );

		if (abs->LoadSurfaceFile(filename))
		{
			_absObjManage.SetABS(abs);
		}
		else
		{
			printf("Error with load file!\n");
			return false;
		}
		goto out;
	}

	if(_wcsicmp(ext, L".obj") == 0)
	{
		MeshModeling* pMeshM = new MeshModeling(lpszPathName);
		_absObjManage.SetMeshModeling(pMeshM);
		goto out;
	}

	if(_wcsicmp(ext, L".pvm") == 0)
	{
		VolumeModeling* volM = new VolumeModeling(lpszPathName);
		_absObjManage.SetVolumeRendering(volM);
		goto out;
	}

out:if(bMorf)
	{
		ABSSf* dest = GetABSObjManage().GetABS();		
		if(_absObjManage._nMorf)
		{
			MorfABSSf* curMorf = _absObjManage.GetMorfABS();
			curMorf->InsertMorfSurf(dest);
			_absObjManage.ResetMorfABS();
			return true;
		}
		else
		{
			MorfABSSf* morAbs = new MorfABSSf(ori, dest);
			_absObjManage.SetMorfABS(morAbs);
			return true;
		}
	}

	return true;
}

bool CObjManageFactory::GenerateRandom()
{	
	ClearAllObject();
	ABSSf* abs = new ABSSf;
	int deg[3] = {2, 2, 2};
	int knotN[3] = {2*(deg[0]+1), 2*(deg[1]+1), 2*(deg[2]+1)};
	abs->GenerateRandomSC(knotN, deg);
	_absObjManage.SetABS(abs);
	
	return true;
}

bool CObjManageFactory::WriteObject(LPCTSTR lpszPathName)
{
	// Not implemented in current project
	const WCHAR* ext = wcsrchr( lpszPathName, L'.');
	if(!ext) 		return false;

	if(_wcsicmp(ext, L".pvm") == 0)
	{
		unsigned int COMPONENTS = 8;		
		_absObjManage.GetMeshModeling()->SaveVolData(lpszPathName, COMPONENTS);
	}
	if(_wcsicmp(ext, L".fmd") == 0)
	{
		//bSuccess = (_absObjManage.GetFengModeling())->OnSaveModel(lpszPathName);
		printf("No implementation!\n");
	}
	else if(_wcsicmp(ext, L".abs") == 0)
	{
		printf("No implementation!\n");
	}

	return true;;	
}
